package com.scut.scutzone.controller;


import com.alibaba.fastjson.JSONArray;
import com.scut.scutzone.config.HttpSessionAttribute;
import com.scut.scutzone.config.ScutZoneConfig;
import com.scut.scutzone.entity.User;
import com.scut.scutzone.exception.BusinessException;
import com.scut.scutzone.service.DatabaseService;
import com.scut.scutzone.util.FileUtil;
import com.scut.scutzone.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private DatabaseService databaseService;
    @Autowired
    private ScutZoneConfig scutZoneConfig;

    /**
     * @description 注册接口
     * @param params 传入JSON格式请求体 RequestBody
     *               Key - Value
     *               username : String - 用户名
     *               password : String - 密码
     *               check_pwd : String - 二次输入密码，此方法会对密码一致性进行校验
     */
    @PostMapping("/register")
    @ResponseBody
    public Result createUser(@RequestBody Map<String, String> params) {
        if (!params.get("password").equals(params.get("check_pwd"))) {
            throw new BusinessException(400, "两次输入的密码不一致");
        }

        databaseService.createUser(params.get("username"), params.get("password"));
        return Result.success("OK", null);
    }

    /**
     * @description 修改密码接口
     * @param session 用户会话状态
     * @param params 传入JSON格式请求体 RequestBody
     *               Key - Value
     *               old_password : String - 旧密码
     *               password : String - 新密码
     *               check_pwd : String - 二次输入新密码，此方法会对密码一致性进行校验
     */
    @PutMapping("/me/password")
    @ResponseBody
    public Result updateUserPassword(@RequestBody Map<String, String> params,
                                     HttpSession session) {
        String uuid = (String) session.getAttribute(HttpSessionAttribute.USER_UUID);
        String oldPassword = params.get("old_password");
        //新密码和重复密码
        String newPassword = params.get("password");
        String check_pwd = params.get("check_pwd");
        if (!newPassword.equals(check_pwd)) {
            throw new BusinessException(400, "两次输入的密码不一致");
        }
        databaseService.updateUserPassword(uuid, oldPassword, newPassword);
        return Result.success("OK", null);
    }

    /**
     * @description 修改个人信息接口
     * @param session 用户会话状态
     * @param params 传入JSON格式请求体 RequestBody
     */
    @PutMapping("/me/info")
    @ResponseBody
    public Result updateUserInfo(@RequestBody Map<String, Object> params, HttpSession session) {
        String uuid = (String) session.getAttribute(HttpSessionAttribute.USER_UUID);
        databaseService.updateUserInfo(uuid, params);
        return Result.success("OK", null);
    }

    /**
     * @description 获取个人信息接口
     * @param uuid Get请求传入参数 最优先根据uuid查找
     * @param username Get请求传入参数 优先级次于uuid
     * @param session 若没有传入uuid和username，则从session中获取当前uuid获取信息
     */
    @GetMapping("")
    @ResponseBody
    public Result getUserInfo(@RequestParam(value = "uuid", required = false) String uuid,
                              @RequestParam(value = "username", required = false) String username,
                              HttpSession session) {
        //若不传uuid和username参数，这两个参数是null
        if ((uuid == null || uuid.isEmpty()) && (username == null || username.isEmpty())) {
            uuid = (String) session.getAttribute(HttpSessionAttribute.USER_UUID);
        }
        String searcher_uuid= (String) session.getAttribute(HttpSessionAttribute.USER_UUID);
        Object userInfo=databaseService.getUserInfo(uuid,username,searcher_uuid);
        return Result.success(userInfo);
    }

    /**
     * @description 模糊搜索用户接口
     * @param keyword Get请求传入参数 查找关键字 必需
     * @param lastUserUUID Get请求传入参数 未知作用
     * @param limit 返回用户数量限制
     */
    @GetMapping("/search")
    @ResponseBody
    public Result searchUsers(@RequestParam(value = "keyword") String keyword,
                              @RequestParam(value = "last_user_uuid", required = false) String lastUserUUID,
                              @RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit,
                              HttpSession session) {
        if (lastUserUUID == null) {
            lastUserUUID = (String) session.getAttribute(HttpSessionAttribute.USER_UUID);
        }
        JSONArray result = databaseService.searchUsers(lastUserUUID,keyword, limit);
        return Result.success("OK", result);
    }

    /**
     * @description 更新头像接口
     * @param avatarFile form-data 传入Multipart图片
     * @param session 当前会话状态，作为更新头像的目标
     */
    @PutMapping("/me/avatar")
    @ResponseBody
    public Result updateUserAvatar(@RequestParam(value = "avatar") MultipartFile avatarFile,
                                   HttpSession session) throws IOException {
        if (!avatarFile.isEmpty()) {
            String filename = FileUtil.saveImage(scutZoneConfig.getRoot_path()+scutZoneConfig.getAvatar_img_path()
                                                 , avatarFile);
            databaseService.updateAvatar((String) session.getAttribute(HttpSessionAttribute.USER_UUID), filename);
            return Result.success("OK", filename);
        } else {
            throw new BusinessException(400,"上传失败");
        }
    }

    /**
     * @description 更新背景图接口
     * @param bgFile form-data 传入Multipart图片
     * @param session 当前会话状态，作为更新背景图的目标
     */
    @PutMapping("/me/bg")
    @ResponseBody
    public Result updateUserBackground(@RequestParam(value = "bg") MultipartFile bgFile,
                                   HttpSession session) throws IOException {
        if (!bgFile.isEmpty()) {
            String filename = FileUtil.saveImage(scutZoneConfig.getRoot_path()+scutZoneConfig.getBg_img_path(),
                                                 bgFile);
            databaseService.updateBackgroundImageName((String) session.getAttribute(HttpSessionAttribute.USER_UUID), filename);
            return Result.success("OK", filename);
        } else {
            throw new BusinessException(400,"上传失败");
        }
    }

    /**
     * @description 关注/取关用户接口
     * @param session 当前会话状态
     * @param params JSON格式请求体 RequestBody
     *               Key - Value
     *               username : String - 需要关注/取关的用户名
     *               status : Boolean - false为需要取关 true为需要关注
     */
    @PutMapping("/me/follow")
    @ResponseBody
    public Result followUser(@RequestBody Map<String, Object> params,
                             HttpSession session) {
        String username = (String) params.get("username");
        if(username==null||username.isEmpty()) {
            throw new BusinessException(400, "用户名错误");
        }
        if(username.equals(session.getAttribute(HttpSessionAttribute.USERNAME))) {
            throw new BusinessException(400, "无法关注自己");
        }

        Boolean status = (Boolean) params.get("status");
        if(status==null) {
            throw new BusinessException(400, "请选择要进行的操作");
        }
        int statusInt = status?1:0;
        databaseService.followUser((String)session.getAttribute(HttpSessionAttribute.USER_UUID), username, statusInt);
        return Result.success("取关/关注成功");
    }

    @GetMapping("/fans")
    @ResponseBody
    public Result getFansList(@RequestParam(value = "uuid", required = false) String uuid,
                              @RequestParam(value = "username", required = false) String username,
                              @RequestParam(value = "last_follow_id", required = false) String lastFollowId,
                              @RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit,
                              HttpSession session) {
        return Result.success("OK", databaseService.getFansJSONArray(username, limit));
    }

    @GetMapping("/follow")
    @ResponseBody
    public Result getFollowerList(@RequestParam(value = "uuid", required = false) String uuid,
                              @RequestParam(value = "username", required = false) String username,
                              @RequestParam(value = "last_follow_id", required = false) String lastFollowId,
                              @RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit,
                              HttpSession session) {
        return Result.success("OK", databaseService.getFollowJSONArray(username, limit));
    }
}